package cn.dogger.easyboot.common.page.aspect;

import cn.dogger.easyboot.common.page.bean.PageData;
import cn.dogger.easyboot.common.util.ServletUtils;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import cn.dogger.easyboot.common.page.annotation.Page;

import java.lang.reflect.Method;

/**
 * @author dogger
 * 分页注解切面
 * 2021/7/30 14:48
 */
@Aspect
@Component
@Slf4j
public class PageAspect {
    /**
     * 切点: 所有配置 DataSource 注解的方法
     * annotation 在方法注解
     * within 在类上注解
     */
    @Pointcut("@annotation(cn.dogger.easyboot.common.page.annotation.Page)")
    public void pageAspectCut() {}


    /**
     * 切面
     * @param point  AOP代理链执行的方法
     * @return 分页列表
     * @throws Throwable 异常
     */
    @Around("pageAspectCut()")
    public PageData around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature sign = (MethodSignature) point.getSignature();
        Method method = sign.getMethod();
        Page annotation = method.getAnnotation(Page.class);
        //request的每页数量
        Integer pageSize = ServletUtils.getRequestInt(PageData.PAGE_SIZE);
        //request的页数
        Integer page = ServletUtils.getRequestInt(PageData.PAGE);
        //需要排序的列
        String orderByColumn = annotation.orderByColumn();
        //需要排序的列
        boolean isAsc = annotation.isAsc();
        //分页合理化
        boolean reasonable = annotation.reasonable();
        if(page ==null ){
            page = annotation.page();
        }
        if(pageSize ==null){
            pageSize = annotation.pageSize();
        }
        //构建分页
        com.github.pagehelper.Page<Object> objectPage;
        if(StringUtils.isBlank(orderByColumn)){
            //不需要排序列
            objectPage = PageHelper.startPage(page,pageSize);
        }else{
            String orderBy = isValidOrderBySql(orderByColumn);
            orderBy = orderBy + " " + (isAsc ? "asc" : "desc");
            objectPage =  PageHelper.startPage(page, pageSize, orderBy).setReasonable(reasonable);
        }
        //执行被切方法
        point.proceed();
        return new PageData(objectPage.getResult(),objectPage.getTotal());
    }

    /**
     * 仅支持字母、数字、下划线、空格、逗号、小数点（支持多个字段排序）
     */
    public static String SQL_PATTERN = "[a-zA-Z\\d_ ,.]+";
    public String isValidOrderBySql(String orderBy){
        if(StringUtils.isNotBlank(orderBy) && orderBy.matches(SQL_PATTERN)){
            return orderBy;
        }else{
            throw new RuntimeException("注解@Page中orderBy字段错误!");
        }
    }
}
